#include "gd32f30x.h"
#include "stdint.h"
#include "stdio.h"

#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"

#include "cdc_acm_core.h"

#include "DevicesQueue.h"
#include "DevicesSoftTimer.h"

#include "DriverUSB.h"


/* USB CDC 句柄 */
static usb_dev st_usbd_cdc;


void vUSBInit(void)
{
    uint32_t system_clock = rcu_clock_freq_get(CK_SYS);

    /* enable USB pull-up pin clock */ 
    rcu_periph_clock_enable(RCU_AHBPeriph_GPIO_PULLUP);

    gpio_bit_set(USB_PULLUP, USB_PULLUP_PIN);

    /* configure usb pull-up pin */
    gpio_init(USB_PULLUP, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, USB_PULLUP_PIN);


    if (48000000U == system_clock)
    {
        rcu_usb_clock_config(RCU_CKUSB_CKPLL_DIV1);
    } 
    else if (72000000U == system_clock)
    {
        rcu_usb_clock_config(RCU_CKUSB_CKPLL_DIV1_5);
    } 
    else if (96000000U == system_clock)
    {
        rcu_usb_clock_config(RCU_CKUSB_CKPLL_DIV2);
    } 
    else if (120000000U == system_clock)
    {
        rcu_usb_clock_config(RCU_CKUSB_CKPLL_DIV2_5);
    }

    /* enable USB APB1 clock */
    rcu_periph_clock_enable(RCU_USBD);

    /* USB device configuration */
    usbd_init(&st_usbd_cdc, &cdc_desc, &cdc_class);


    /* enable the USB low priority interrupt */
    nvic_irq_enable((uint8_t)USBD_LP_CAN0_RX0_IRQn, 7U, 0U);

    /* enable the USB low priority interrupt */
 //   nvic_irq_enable((uint8_t)USBD_HP_CAN0_TX_IRQn, 7U, 0U);


    /* enabled USB pull-up */
    usbd_connect(&st_usbd_cdc);

    /* wait for standard USB enumeration is finished */
//    while (USBD_CONFIGURED != st_usbd_cdc.cur_status);
}

/* 此函数只给USB官方库函数进行回调使用 */
int8_t cUSBCDCReceiveDatas(uint8_t *pucBuff, int32_t iLength)
{
    /* 把一帧数据读取到UART队列缓存里 */
    enumQueuePushDatas(&g_TypeQueueUSBRead, pucBuff, iLength);

    /* 给出信号量，以启动任务执行解析 */
//    xTaskNotifyFromISR(g_TaskMessageSlaveHand, 0x01, eSetBits, NULL);

    return 0;
}

int8_t cUSBCDCSendDatas(void *pvBuff, int32_t iLength)
{
    cdc_acm_datas_send(&st_usbd_cdc, pvBuff, iLength);

    return 0;
}
